// smrs.h
#ifndef SMRS_H
#define SMRS_H

#include "xil_types.h" // For u32, u64, etc.
#include "smrs_config.h" // 包含所有配置常量
#include "vdma_display.h" // 引用 VdmaDisplay 结构体
#include "xgpu_render_tbr.h" // 引用 HLS IP 驱动

// SMRS 模块状态码
#define SMRS_SUCCESS XST_SUCCESS
#define SMRS_FAILURE XST_FAILURE

// HLS IP 期望的 PS 端三角形数据结构
// 此结构体应由应用程序在将数据提交给 SMRS 模块前填充
// 颜色直接使用 float，在打包时转换为 u8
typedef struct {
    float v0x, v0y, v0z_norm; // 归一化Z值 [0, 1]
    float v1x, v1y, v1z_norm;
    float v2x, v2y, v2z_norm;
    float r_f, g_f, b_f;        // 颜色分量 (float表示，0-255范围)
    // Edge equation coefficients
    float edge0_A, edge0_B, edge0_C;
    float edge1_A, edge1_B, edge1_C;
    float edge2_A, edge2_B, edge2_C;
    // Depth gradients (dz/dx, dz/dy)
    float dzdx, dzdy;
} SmrsTriangle;

// SMRS 模块实例结构体
typedef struct {
    XGpu_render_tbr GpuRenderTbrInstance; // HLS GPU IP 驱动实例
    // 渲染分辨率由 VDMA Display 模块提供
    u32 render_width;
    u32 render_height;
    u32 hls_single_frame_size; // HLS 帧缓冲区大小

    smrs_ddr_word_t* params_buffer; // PS 端用于打包三角形数据的 DDR 内存
    u16* zbuffer_raw_ptr;           // PS 端 ZBuffer 的 DDR 内存
    u32 zbuffer_size_bytes;         // ZBuffer 的字节大小
} SmrsContext;

/**
 * @brief 初始化 SMRS 模块。
 *        包括初始化 HLS GPU IP 驱动，并分配 DDR 缓冲区。
 *
 * @param pContext 指向 SmrsContext 实例的指针。
 * @param vdma_display_ptr 指向 VdmaDisplay 实例的指针，用于获取渲染分辨率。
 * @return SMRS_SUCCESS (0) if successful, SMRS_FAILURE (1) otherwise.
 */
int Smrs_Init(SmrsContext* pContext, const VdmaDisplay* vdma_display_ptr);

/**
 * @brief 在 DDR 中清空当前渲染帧的 HLS 帧缓冲区和 ZBuffer。
 *        SMRS 模块仅负责清空，不关心渲染逻辑。
 *
 * @param pContext 指向 SmrsContext 实例的指针。
 * @param current_hls_framebuffer_addr 当前要清空的 HLS 帧缓冲区的物理地址。
 * @return SMRS_SUCCESS if successful, SMRS_FAILURE otherwise.
 */
int Smrs_ClearFrameAndZBuffer(SmrsContext* pContext, UINTPTR current_hls_framebuffer_addr);

/**
 * @brief 将 SmrsTriangle 数组打包并调度到 HLS GPU IP 进行渲染。
 *        此函数是 SMRS 模块的核心渲染调度接口。
 *
 * @param pContext 指向 SmrsContext 实例的指针。
 * @param triangles 指向 SmrsTriangle 数组的指针，包含要渲染的三角形数据。
 * @param num_triangles 数组中三角形的数量。
 * @param target_hls_framebuffer_addr 渲染目标 HLS 帧缓冲区的物理地址。
 * @return SMRS_SUCCESS if rendering is successfully dispatched and completed, SMRS_FAILURE otherwise.
 */
int Smrs_RenderTriangles(SmrsContext* pContext, const SmrsTriangle* triangles, u32 num_triangles, UINTPTR target_hls_framebuffer_addr);


/**
 * @brief 将 R, G, B 分量打包成 32 位颜色槽 (低 24 位是 BGR)。
 *        此函数为公共实用工具，主要用于 PS 端初始化 Frame Buffer 或验证读取。
 *        与 HLS 端打包逻辑保持一致：B (bits 0-7), G (bits 8-15), R (bits 16-23)。
 *        高 8 位为 0 (0x00RRGGBB)。
 * @param r, g, b 颜色分量 (0-255)
 * @return 打包后的 32 位颜色槽值 (u32)，高 8 位为 0。
 */
u32 Smrs_PackRgbTo32BitSlot(u8 r, u8 g, u8 b);

/**
 * @brief 计算三角形的边缘方程系数 (Ax + By + C = 0)。
 * @param v0x, v0y, v1x, v1y, v2x, v2y 屏幕空间顶点坐标。
 * @param A0, B0, C0, A1, B1, C1, A2, B2, C2 输出边缘方程系数。
 */
void Smrs_CalculateEdgeEquations(
    float v0x, float v0y, float v1x, float v1y, float v2x, float v2y,
    float* A0, float* B0, float* C0,
    float* A1, float* B1, float* C1,
    float* A2, float* B2, float* C2
);

/**
 * @brief 计算深度梯度 (dzdx, dzdy)。
 *        z 值应为 HLS IP 期望的 Z Buffer 范围值 (例如 [0, 65535])。
 * @param v0x, v0y, v0z, v1x, v1y, v1z, v2x, v2y, v2z 屏幕空间顶点坐标和 Z 值。
 * @param dzdx, dzdy 输出深度梯度。
 */
void Smrs_CalculateDepthGradients(
    float v0x, float v0y, float v0z,
    float v1x, float v1y, float v1z,
    float v2x, float v2y, float v2z,
    float* dzdx, float* dzdy
);


#endif // SMRS_H

